﻿////*********************************************************************
////<copyright file="XMLConverter.cs" company="Cognizant">
////Solution Name:InfoPath XML Converter
////Document author:Shlok Chakankar
////FILENAME: "XMLConverter.cs"
////PURPOSE: Solution to convert all existing InfoPath 2007 forms into InfoPath 2010
////HISTORY:18/07/2012-Project Created
////</copyright>
////*********************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Xml.XPath;
using System.Text.RegularExpressions;
using System.Configuration;
using Microsoft.SharePoint;
using DocumentFormat.OpenXml.Packaging;
using Microsoft.Office.InfoPath;

namespace InfoPath_XML_Converter
{
    class XMLConverter
    {
        static void Main(string[] args)
        {
            try
            {
                string strSiteUrl = ConfigurationManager.AppSettings["SiteUrl"];
                string strWebUrl = ConfigurationManager.AppSettings["WebUrl"];
                string strListName = ConfigurationManager.AppSettings["ListName"];
                using (SPSite site = new SPSite(strSiteUrl))
                {
                    using (SPWeb web = site.OpenWeb(strWebUrl))
                    {
                        ////Get handle for forms library            
                        SPList formsLib = web.Lists[strListName];
                        if (formsLib != null)
                        {
                            foreach (SPListItem item in formsLib.Items)
                            {
                                try
                                {
                                    XmlDocument xml = new XmlDocument();
                                   ////Open XML file and load it into XML document                     
                                    using (Stream s = item.File.OpenBinaryStream())
                                    { 
                                        xml.Load(s); 
                                    }

                                    XmlNamespaceManager NamespaceManager = new XmlNamespaceManager(xml.NameTable);
                                    XmlNode infoVersion = xml.FirstChild.NextSibling;
                                    //// Get all People Picket
                                    XmlNodeList nodes = xml.GetElementsByTagName("my:Person");
                                    int nodeCount = nodes.Count;
                                    if (nodeCount != 0)
                                    {
                                        for (int i = 0; i < nodeCount; i++)
                                        {
                                            if (nodes[0] != null)
                                            {
                                                XmlNode currentNode = nodes[0];
                                                if (string.IsNullOrEmpty(nodes[0].FirstChild.InnerText))
                                                {
                                                    nodes[0].ParentNode.InnerXml = "";
                                                }
                                                else
                                                {
                                                    //// Update InfoPath 2007 tags to make it InfoPath 2010 compatible
                                                    if (!nodes[0].OuterXml.ToString().Contains("xmlns:my"))
                                                    {
                                                        XmlAttribute att = xml.CreateAttribute("xmlns:pc");
                                                        att.Value = "http://schemas.microsoft.com/office/infopath/2007/PartnerControls";
                                                        nodes[0].Attributes.RemoveAll();
                                                        nodes[0].Attributes.Append(att);
                                                    }

                                                    string strOuterXml = nodes[0].OuterXml;
                                                    strOuterXml = Regex.Replace(strOuterXml, "my:", "pc:");

                                                    strOuterXml = Regex.Replace(strOuterXml, "xmlns:my", "xmlns:pc");
                                                    string strReplace = strOuterXml.Substring(strOuterXml.IndexOf("http://schemas.microsoft.com/office/infopath/2003/myXSD"), 75);
                                                    strOuterXml = Regex.Replace(strOuterXml, strReplace, "http://schemas.microsoft.com/office/infopath/2007/PartnerControls");

                                                    nodes[0].ParentNode.InnerXml = strOuterXml;
                                                }
                                            }
                                        }
                                    }
                                    //// Add attibutes in header of InfoPath header
                                    XmlNodeList fields = xml.GetElementsByTagName("my:myFields");
                                    int fieldCount = fields.Count;
                                    if (fieldCount != 0)
                                    {
                                        XmlAttribute att1 = xml.CreateAttribute("xmlns:pc");
                                        att1.Value = "http://schemas.microsoft.com/office/infopath/2007/PartnerControls";
                                        XmlAttribute att2 = xml.CreateAttribute("xmlns:ma");
                                        att2.Value = "http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes";
                                        XmlAttribute att3 = xml.CreateAttribute("xmlns:d");
                                        att3.Value = "http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields";
                                        XmlAttribute att4 = xml.CreateAttribute("xmlns:q");
                                        att4.Value = "http://schemas.microsoft.com/office/infopath/2009/WSSList/queryFields";
                                        XmlAttribute att5 = xml.CreateAttribute("xmlns:dms");
                                        att5.Value = "http://schemas.microsoft.com/office/2009/documentManagement/types";

                                        fields[0].Attributes.Append(att1);
                                        fields[0].Attributes.Append(att2);
                                        fields[0].Attributes.Append(att3);
                                        fields[0].Attributes.Append(att4);
                                        fields[0].Attributes.Append(att5);
                                    }
                                    ////Get binary data for new XML 
                                    byte[] xmlData = System.Text.Encoding.UTF8.GetBytes(xml.OuterXml);
                                    using (MemoryStream ms = new MemoryStream(xmlData))
                                    {
                                        ////Write data to SharePoint XML file   
                                        item.File.SaveBinary(ms);
                                        Console.WriteLine("InfoPath form -" + item["Name"].ToString() + " updated.");
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine("Error:-" + ex.Message);
                                    Console.ReadKey();
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error:-" + ex.Message);
                Console.ReadKey();
            }
        }
    }
}
